/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufpr.inf.escel.brain.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 *
 * @author gustavo
 */
public class StringUtils {

    private static final String[] ALFA_MAISCULO = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "X", "Y", "Z"};
    private static final String[] ALFA_MINUSCULO = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "x", "y", "z"};
    private static final String[] ASCII = getAscii();

    /**
     * Gera um vetor com os elementos da tabela ascii
     * @return ascii vector
     */
    private static String[] getAscii() {

        List<String> ascii = new ArrayList<String>();

        for (int i = 32; i <= 126; i++) {
            String caracter = Character.toString((char) i);
            if (!caracter.equals("'")) {
                ascii.add(caracter);
            }
        }

        ascii.add("");
        ascii.add("\n");
        ascii.add("\t");
        ascii.add("    ");

        return PrimitivosUtils.listToArray(ascii);
    }

    /**
     * Metodo que gera um bloco do cromossomo para um determinado
     * vetor de entrada. Para tal, os elementos do vetor são sorteados
     * por uma problabilidade de 50%, igual ao de jogar uma moeda
     * 
     * @param vetor de strings
     * @return uma string com caracteres sorteados
     * @since 0.3
     */
    public static String gerarTipoString() {

        StringBuffer saida = new StringBuffer();

        for (int i = 0; i <= ALFA_MAISCULO.length - 1; i++) {
            int moeda = (int) (Math.random() + 0.3);

            //sorteia se o caracter vai entrar na string
            //probabilidade de 30%
            saida.append((moeda == 1) ? ALFA_MAISCULO[i] : "");
        }

        return saida.toString();
    }

    /**
     * Sorteia um inteiro no intervalo entre 0~99
     * @return inteiro entre 0~99
     */
    public static Integer gerarTipoInteiro() {
        Random r = new Random();
        return r.nextInt(100);
    }

    /**
     * Gera elementos de entrada para o programa getcmd.
     * Tais elementos vão tanto ser uteis par a construção da 
     * população inical, quanto para a mutação.
     * @return dado de teste p/ o programa getcmd
     */
    public static String getcmd() {

        StringBuffer out = new StringBuffer();

        int primeiro = (int) (Math.random() * ALFA_MINUSCULO.length);
        int segundo = (int) (Math.random() * ALFA_MINUSCULO.length);
        
        out.append(ALFA_MINUSCULO[primeiro]).append(ALFA_MINUSCULO[segundo]);

        return out.toString();
    }

    /**
     * Gera uma string com um incidenca de caracteres repetidos.
     * Método excencial para o problema compress.c
     * @return aaaabbbbcccc
     */
    public static String compress() {
        StringBuffer saida = new StringBuffer("");

        double hasChave = Math.random();
        if (hasChave > 0.7) {
            //digo chave, pq eles são importantes
            String[] chaves = {"", "\n", "\t", " ", "     ", "\"", "\b"};
            int elemento = (int) (Math.random() * chaves.length);
            saida.append(chaves[elemento]);

        } else {
            for (int i = 0; i <= ASCII.length - 1; i++) {
                double moeda = Math.random();

                if (moeda > 0.5) {
                    int repeticoes = (int) (Math.random() * 10);

                    for (int j = 0; j < repeticoes; j++) {
                        saida.append(ASCII[i]);
                    }
                }
            }
        }
        return saida.toString();
    }

    /**
     * Sorteia um caracter aleatório utilizando a codificação ASCII
     * 
     * @return caracter aleatório entre a~z
     * @since 0.4
     */
    public static char gerarTipoChar() {
        return (char) (Math.random() * 26 + 97);
    }

    /**
     * Verifica se a string contem algum dos caracteres.
     * Esse método é util na comparação do cromossomo para PP, 
     * quando verificado a qual tipo de bloco ele pertence. Não
     * encontrei algum metodo pronto, por isso escrevi esse.
     * Possivelmente, ele não será utilizado em outro lugar.
     * 
     * @param string
     * @return true caso contenha, false por outro lado
     * @since 1.3
     */
    public static boolean hasSomeChar(String valor) {
        for (int i = 0; i < ALFA_MAISCULO.length; i++) {
            if (valor.contains(ALFA_MAISCULO[i])) {
                return true;
            }
        }
        return false;
    }
}
